package com.hr.service.impl;

import com.hr.domain.po.House;
import com.hr.domain.po.HouseFacility;
import com.hr.domain.po.HouseImage;
import com.hr.domain.po.User;
import com.hr.domain.vo.UserHouseDetails;
import com.hr.mapper.HouseFacilityMapper;
import com.hr.mapper.HouseImageMapper;
import com.hr.mapper.HouseMapper;
import com.hr.mapper.UserMapper;
import com.hr.service.FavoriteService;
import com.hr.service.RedisHouseService;
import com.hr.service.UserHouseService;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;


@Service
@AllArgsConstructor
public class RedisHouseServiceImpl implements RedisHouseService {
    private final RedisTemplate<String, Object> redisTemplate;

    private final HouseMapper houseMapper;

    private final HouseFacilityMapper houseFacilityMapper;

    private final HouseImageMapper houseImageMapper;

    private final UserHouseService userHouseService;


    /*===================定义Redis属性======================*/
    // 热门房源点击量阈值
    private static final int HOT_HOUSE_THRESHOLD = 15;
    // 热门房源数量阈值
    private static final int HOT_HOUSE_COUNT = 12;
    // 缓存过期时间(2小时)
    private static final long CACHE_EXPIRE_SECONDS = 7200;
    // 房源点击量有序集合key
    private static final String HOUSE_CLICK_RANK_KEY = "house:click:rank";
    // 房源详情缓存key前缀
    private static final String HOUSE_DETAILS_CACHE_PREFIX = "house:details:";
    // 用户收藏缓存key前缀
    private static final String USER_COLLECT_HOUSE_PREFIX = "user:collect:house:";

    /*=========================方法实现=========================*/
    /*
    * 房源详情点击量
    * */
    @Override
    public void clickHouseDetailsViews(Long houseId) {
        // 每次点击，在有序集合中增加1分
        redisTemplate.opsForZSet().incrementScore(HOUSE_CLICK_RANK_KEY, houseId, 1);
    }
    /*
    * 判断房源是否为热门房源
    * */
    @Override
    public boolean isHotHouse(Long houseId) {
        // 从有序集合中获取分数
        Double score = redisTemplate.opsForZSet().score(HOUSE_CLICK_RANK_KEY, houseId);
        if (score != null && score >= HOT_HOUSE_THRESHOLD) {
            return true;
        }
        return false;
    }
    /*
    * 获取热门房源列表
    * */
    @Override
    public List<Long> getHotHouseIds(int count) {
        // 获取有序集合中指定范围的元素
        ZSetOperations<String, Object> stringObjectZSetOperations = redisTemplate.opsForZSet();
        //解释: reverseRange(key, 0, count - 1), 表示获取有序集合中从0到count-1的元素，包含0和count-1
        Set<Object> houseIds = stringObjectZSetOperations.reverseRange(HOUSE_CLICK_RANK_KEY, 0, count - 1);
        if (houseIds == null || houseIds.isEmpty()) {
            return null;
        }
        // Set集合中的元素是Object类型，需要转换为Long类型，使用stream流，转换为Long类型
        // 安全地将Object转换为Long类型
        return houseIds.stream()
                .map(id -> {
                    if (id instanceof Long) {
                        return (Long) id;
                    } else if (id instanceof Integer) {
                        return ((Integer) id).longValue();
                    } else {
                        return Long.valueOf(id.toString());
                    }
                })
                .toList();

    }
    /*
    * 从缓存中获取房源详情
    * */
    @Override
    public UserHouseDetails getHouseDetailsFromCache(Long houseId, Long userId) {
        //1.拼接成所能在缓存中能找到的key
        String cacheKey = HOUSE_DETAILS_CACHE_PREFIX + houseId;
        //2.从缓存中获取数据
        UserHouseDetails  houseDetails  = (UserHouseDetails)redisTemplate.opsForValue().get(cacheKey);
        if (houseDetails != null && userId != null) {
            // 补充判断当前用户是否收藏
            Boolean isCollected = userHouseService.isUserCollectedHouse(userId, houseId);
            houseDetails.setIsCollected(isCollected);
        }
        return houseDetails;
    }
    /*
    * 保存房源详情到缓存
    * */
    @Override
    public void saveHouseDetailsToCache(UserHouseDetails houseDetails, long expireSeconds) {
        //判断houseDetails是否为空
        if (houseDetails == null || houseDetails.getId() == null) {
            return;
        }
        //1.拼接成所能在缓存中能找到的key
        String cacheKey = HOUSE_DETAILS_CACHE_PREFIX + houseDetails.getId();
        //2.保存数据
        redisTemplate.opsForValue().set(cacheKey, houseDetails, expireSeconds, TimeUnit.SECONDS);
    }
    /*
    * 清除房源缓存
    * */
    @Override
    public void clearHouseCache(Long houseId) {
        //1.拼接成所能在缓存中能找到的key
        String cacheKey = HOUSE_DETAILS_CACHE_PREFIX + houseId;
        //2.删除缓存数据
        redisTemplate.delete(cacheKey);
    }
    /*
    * 清除所有热门房源缓存
    * */
    @Override
    public void clearHotHouseCache() {
        //1.删除有序集合数据
        redisTemplate.delete(HOUSE_CLICK_RANK_KEY);
        //2.删除所有缓存数据
        redisTemplate.delete(redisTemplate.keys(HOUSE_DETAILS_CACHE_PREFIX + "*"));

    }

    /**
     * 构建房屋详情
     * @param houseId 房源ID
     * @param userId 用户ID
     * @return 房源详情
     */
    @Override
    public UserHouseDetails buildHouseDetails(Long houseId, Long userId){
        // 1. 获取房屋基本信息
        UserHouseDetails details = houseMapper.getHouseDetailsById(houseId);
        if (details == null) {
            return null;
        }
        // 2. 获取房屋设施信息
        List<HouseFacility> houseFacilityList = houseFacilityMapper.getHouseFacilityListById(houseId);
        details.setFacilityList(houseFacilityList);

        // 3. 获取房屋图片信息
        List<HouseImage> houseImageList = houseImageMapper.getHouseImageListById(houseId);
        details.setHouseImageList(houseImageList);

        // 4. 获取是否收藏
        if (userId != null) {
            Boolean isCollected = userHouseService.isUserCollectedHouse(userId, houseId);
            details.setIsCollected(isCollected);
        }
        return details;
    }


}
